#!/usr/bin/env python
#coding=utf-8

import json
from pprint import pprint, pformat

from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkslb.request.v20140515.DescribeVServerGroupAttributeRequest import DescribeVServerGroupAttributeRequest
from aliyunsdkslb.request.v20140515.DescribeVServerGroupsRequest import DescribeVServerGroupsRequest
from aliyunsdkslb.request.v20140515.SetVServerGroupAttributeRequest import SetVServerGroupAttributeRequest
from aliyunsdkslb.request.v20140515.RemoveVServerGroupBackendServersRequest import RemoveVServerGroupBackendServersRequest
from aliyunsdkslb.request.v20140515.AddVServerGroupBackendServersRequest import AddVServerGroupBackendServersRequest
from aliyunsdkslb.request.v20140515.ModifyVServerGroupBackendServersRequest import ModifyVServerGroupBackendServersRequest

from aliyun_client import AliYunClient
from aliyun_slb import AliyunSlb
import pandas as pd
import logging
from welab_logging import logs


class AliyunSlbVServer(object):
    def __init__(self):
        self.logger = logging.getLogger('welab.aliyun.slb')
        self.aliyun_slb = AliyunSlb()
        self.aliyun_client = AliYunClient()
        self.aliyun = self.aliyun_client.get_all_client()



    def get_aliyun_vserver_group_info(self, account, vserver_group_id):
        try:
            request = DescribeVServerGroupAttributeRequest()
            request.set_accept_format('json')
            request.set_VServerGroupId(vserver_group_id)

            response = account["client"].do_action_with_exception(request)
            response = json.loads(str(response, encoding='utf-8'))
            backend_server = response["BackendServers"]["BackendServer"]
        except Exception as e:
            self.logger.error(f"vserver_group:{vserver_group_id} get info error => {e}")
            return False

        return backend_server


    def get_slb_vserver_group_info(self, account, slb_id):
        try:
            vserver_group_info = []
            request = DescribeVServerGroupsRequest()
            request.set_accept_format('json')
            request.set_LoadBalancerId(slb_id)
            request.set_IncludeListener(True)

            response = account["client"].do_action_with_exception(request)
            response = json.loads(str(response, encoding='utf-8'))

            for vserver_group in response["VServerGroups"]["VServerGroup"]:
                info = {
                    "VServerGroupId": vserver_group["VServerGroupId"],
                    "Listeners": vserver_group["AssociatedObjects"]["Listeners"]["Listener"],
                    "VServerGroupName": vserver_group["VServerGroupName"],
                    "BackendServer": self.get_aliyun_vserver_group_info(account, vserver_group["VServerGroupId"])
                }
                vserver_group_info.append(info)

        except Exception as e:
            self.logger.error(f"slb:{slb_id} get vserver_group info error => {e}")
            return False

        return vserver_group_info

    def get_all_vserver_group_info(self):
        slbs_info = self.aliyun_slb.get_all_slb_info()
        for slb_info in slbs_info:
            account = self.aliyun_client.get_one_client(slb_info["account"])
            slb_info["vserver_groups"] = self.get_slb_vserver_group_info(account, slb_info["id"])

        return slbs_info




    def remove_vserver_group(self, account, vserver_group_id, backend_server):
        """ 虚拟服务器组删除一个节点 """
        try:
            BackendServers = [
                {
                    'ServerId': backend_server["ServerId"],
                    'Weight': f'{backend_server["Weight"]}',
                    'Type': 'ecs',
                    'Port': f'{backend_server["Port"]}'
                }
            ]
            request = RemoveVServerGroupBackendServersRequest()
            request.set_accept_format('json')

            request.set_VServerGroupId(vserver_group_id)
            request.set_BackendServers(json.dumps(BackendServers))

            response = account["client"].do_action_with_exception(request)
            self.logger.info(f"remove vserver group {vserver_group_id} => {backend_server['ServerId']} success")
        except Exception as e:
            self.logger.error(f"remove vserver group {vserver_group_id} => {backend_server['ServerId']} error => {e}")
            return False

        return True



    def add_vserver_group(self, account, vserver_group_id, backend_server):
        """ 虚拟服务器组增加一个节点 """
        try:
            BackendServers = [
                {
                    'ServerId': backend_server["ServerId"],
                    'Weight': f'{backend_server["Weight"]}',
                    'Type': 'ecs',
                    'Port': f'{backend_server["Port"]}'
                }
            ]
            request = AddVServerGroupBackendServersRequest()
            request.set_accept_format('json')

            request.set_VServerGroupId(vserver_group_id)
            request.set_BackendServers(json.dumps(BackendServers))

            response = account["client"].do_action_with_exception(request)
            self.logger.info(f"add vserver group {vserver_group_id} => {backend_server['ServerId']} success")
        except Exception as e:
            self.logger.error(f"add vserver group {vserver_group_id} => {backend_server['ServerId']} error => {e}")
            return False

        return True



    def modify_vserver_group(self, account, vserver_group_id, old_backend_server, new_backend_server):
        """ 虚拟服务器组替换一个节点 """
        try:
            OldBackendServers = [
                {
                    'ServerId': old_backend_server["ServerId"],
                    'Weight': f'{old_backend_server["Weight"]}',
                    'Type': 'ecs',
                    'Port': f'{old_backend_server["Port"]}'
                }
            ]
            NewBackendServers = [
                {
                    'ServerId': new_backend_server["ServerId"],
                    'Weight': f'{new_backend_server["Weight"]}',
                    'Type': 'ecs',
                    'Port': f'{new_backend_server["Port"]}'
                }
            ]
            request = ModifyVServerGroupBackendServersRequest()
            request.set_accept_format('json')

            request.set_VServerGroupId(vserver_group_id)
            request.set_OldBackendServers(json.dumps(OldBackendServers))
            request.set_NewBackendServers(json.dumps(NewBackendServers))

            response = account["client"].do_action_with_exception(request)
            self.logger.info(f"modify vserver group {vserver_group_id} => old:{old_backend_server['ServerId']} to new:{new_backend_server['ServerId']} success")
        except Exception as e:
            self.logger.error(f"modify vserver group {vserver_group_id} => old:{old_backend_server['ServerId']} to new:{new_backend_server['ServerId']} error => {e}")
            return False

        return True



    def set_vserver_group(self, account, vserver_group_id, backend_server):
        """ 设置权重 """
        try:
            BackendServers = [
                {
                    'ServerId': backend_server["ServerId"],
                    'Weight': f'{backend_server["Weight"]}',
                    'Type': 'ecs',
                    'Port': '80',
                    'Description': backend_server["hostname"]
                }
            ]
            request = SetVServerGroupAttributeRequest()
            request.set_accept_format('json')

            request.set_VServerGroupId(vserver_group_id)
            request.set_BackendServers(json.dumps(BackendServers))

            response = account["client"].do_action_with_exception(request)
            self.logger.info(f"set vserver group {vserver_group_id} => {backend_server['hostname']}:{backend_server['Weight']} success")
        except Exception as e:
            self.logger.error(f"set vserver group {vserver_group_id} => {backend_server['hostname']}:{backend_server['Weight']} error => {e}")
            return False

        return True



    def batch_modify_waf_weight(self):
        waf_backend_server = {
            "i-wz98m7yqiqob7j8726ux": {
                "hostname": "ct-waf-check01",
                "ip": "192.168.46.220",
                "ServerId": "i-wz98m7yqiqob7j8726ux",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9bzu6ai8kiqouwsn5j": {
                "hostname": "ct-waf-check02",
                "ip": "192.168.47.185",
                "ServerId": "i-wz9bzu6ai8kiqouwsn5j",
                "Weight": 100,
                "Port": 80
            }
        }

        slbs_info = self.get_all_vserver_group_info()
        for slb_info in slbs_info:
            account = self.aliyun_client.get_one_client(slb_info["account"])
            if slb_info["id"] != "lb-wz98h9t8lztfdmgktj1vh":
                continue
            # 遍历slb的所有虚拟服务器组
            for vserver_group in slb_info["vserver_groups"]:
                # 修改虚拟服务器组
                for backend_server in vserver_group["BackendServer"]:
                    if backend_server["ServerId"] in waf_backend_server:
                        self.set_vserver_group(account, vserver_group["VServerGroupId"], waf_backend_server[backend_server["ServerId"]])
                        self.logger.info(f"set slb vserver group {slb_info['name']}:{vserver_group['VServerGroupName']} success")





    def batch_modify_gateway_host(self):
        """ 批量替换api网关的服务器 """
        gateway_server = {
            # welabfintech账号
            "i-wz91m75r951oxn5yjcth": {
                "hostname": "welabfintech-gateway-openresty03",
                "ip": "192.168.103.242",
                "ServerId": "i-wz93unouh5i574y3lvun",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9b7mqnhnv6wl33ms73": {
                "hostname": "welabfintech-gateway-openresty04",
                "ip": "192.168.104.201",
                "ServerId": "i-wz95fq58peyncm2zknvp",
                "Weight": 100,
                "Port": 80
            },
            # wallet账号
            "i-wz9hlxx3hibvaxiyfz5h": {
                "hostname": "wallet-gateway-openresty03",
                "ip": "192.168.11.205",
                "ServerId": "i-wz941vautl96t51ch5uk",
                "Weight": 100,
                "Port": 80
            },
            "i-wz93abvx2l34m0a716nh": {
                "hostname": "wallet-gateway-openresty04",
                "ip": "192.168.12.47",
                "ServerId": "i-wz98xlu92u803d68raa1",
                "Weight": 100,
                "Port": 80
            },
            # sa账号
            "i-wz942g0khndb9dmtcorz": {
                "hostname": "gateway-openresty03",
                "ip": "172.20.60.9",
                "ServerId": "i-wz9c2cm0s954bju0i19w",
                "Weight": 100,
                "Port": 80
            },
            "i-wz92am8wqrn7c3bcb807": {
                "hostname": "gateway-openresty04",
                "ip": "172.21.60.90",
                "ServerId": "i-wz9gkl57308yh4lvqswn",
                "Weight": 100,
                "Port": 80
            },
            # welabconsfin账号
            "i-wz992hxzv1ybsr4hejt3": {
                "hostname": "welabconsfin-gateway-openresty01",
                "ip": "192.168.41.129",
                "ServerId": "i-wz98xlu92u803p0ffm7f",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9ieukla9ky3td246nz": {
                "hostname": "welabconsfin-gateway-openresty02",
                "ip": "192.168.41.130",
                "ServerId": "i-wz96rsdtqvaw4lsuc33f",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9evxymdqdx5om37aay": {
                "hostname": "welabconsfin-gateway-openresty03",
                "ip": "192.168.42.225",
                "ServerId": "i-wz9hpbxcohcpqlew9h7f",
                "Weight": 100,
                "Port": 80
            },
            "i-wz97sm51bf4ksd512st8": {
                "hostname": "welabconsfin-gateway-openresty04",
                "ip": "192.168.42.226",
                "ServerId": "i-wz9c2cm0s954bfvy9x8c",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9257qzx65clrxj6fdk": {
                "hostname": "welabconsfin-gateway-openresty05",
                "ip": "192.168.41.131",
                "ServerId": "i-wz9hpbxcohcpqlew9h7k",
                "Weight": 100,
                "Port": 80
            },
            "i-wz9257qzx65clrxj6fdl": {
                "hostname": "welabconsfin-gateway-openresty06",
                "ip": "192.168.41.132",
                "ServerId": "i-wz96cg8ytvapep3aktjd",
                "Weight": 100,
                "Port": 80
            },
            "i-wz97bu0gr8vx3zjja6ld": {
                "hostname": "welabconsfin-gateway-openresty07",
                "ip": "192.168.42.227",
                "ServerId": "i-wz95fq58peynctz40vvg",
                "Weight": 100,
                "Port": 80
            },
            "i-wz97bu0gr8vx3zjja6o7": {
                "hostname": "welabconsfin-gateway-openresty08",
                "ip": "192.168.42.228",
                "ServerId": "i-wz96cg8ytvapep3aktjg",
                "Weight": 100,
                "Port": 80
            },
        }

        slb_id = [
            "lb-wz9hmqtmc15bm8e2gezgf",
            "lb-wz9fwofj30er3cjh7mao5",
            "lb-wz98h9t8lztfdmgktj1vh",
            "lb-wz9ahego2sdqtedq8jm9w",
            "lb-wz9f0ijvhfh0pye2abevw",
            "lb-wz93a6wp3gwlcokrmosxg",
            "lb-wz9xrpp05u4labrvdt6ma",
            "lb-wz98qg40eohn9gt5a7io2",
            "lb-wz97fid9npjjgu1ajldfb",
            "lb-wz9ycmws2eia07pplc3b9",
            "lb-wz9bqxzpz9vdr7ns0ysmd",
            "lb-wz9wvv697fduni5e2jzsp",
            "lb-wz9rallvn3fg6lyrb7fc5",
            "lb-wz9kvplqv170krlf8knjg",
            "lb-wz9tfiq8fr2g0f7vcvf9n",
            "lb-wz97ufp7vz05ozse8itg4",
            "lb-wz9g7rmjoxuk17rt3pvfn",
            "lb-wz9549o7jaedp0c18qfxi",
            "lb-wz9wzkly8ivgevmug3yyf",
            "lb-wz9cfpcfioc80pjkwxl68",
            "lb-wz9l0ines5ard6ierywjy",
            "lb-wz9807i0t6plxy09zdfop",
            "lb-wz9jbavisuign6fenns04",
            "lb-wz992wispoisv67pz0h2g",
            "lb-wz9lcvjal9f5numdbv4up",
            "lb-wz9b90puxc70xc9qzhbhf",
            "lb-wz9kxooysxs96uq8sv7gv"
        ]

        slbs_info = self.get_all_vserver_group_info()
        for slb_info in slbs_info:
            if slb_info["id"] not in slb_id:
                continue
            account = self.aliyun_client.get_one_client(slb_info["account"])
            # 遍历slb的所有虚拟服务器组
            for vserver_group in slb_info["vserver_groups"]:
                # 修改虚拟服务器组
                for backend_server in vserver_group["BackendServer"]:
                    if backend_server["ServerId"] in gateway_server:
                        self.modify_vserver_group(account, vserver_group["VServerGroupId"], backend_server, gateway_server[backend_server["ServerId"]])
                        self.logger.info(f"modify slb vserver group {slb_info['account']}:{slb_info['name']}:{vserver_group['VServerGroupName']} success")


    def write_vserver_to_excel(self):
        gateway_server = [
            "i-wz93abvx2l34m0a716nh",
            "i-wz9hlxx3hibvaxiyfz5h",
            "i-wz9257qzx65clrxj6fdk",
            "i-wz9257qzx65clrxj6fdl",
            "i-wz97bu0gr8vx3zjja6ld",
            "i-wz97bu0gr8vx3zjja6o7",
            "i-wz97sm51bf4ksd512st8",
            "i-wz992hxzv1ybsr4hejt3",
            "i-wz9evxymdqdx5om37aay",
            "i-wz9ieukla9ky3td246nz",
            "i-wz91m75r951oxn5yjcth",
            "i-wz9b7mqnhnv6wl33ms73",
            "i-wz942g0khndb9dmtcorz",
            "i-wz92am8wqrn7c3bcb807"
        ]
        slbs_info = self.get_all_vserver_group_info()
        data_info = []
        for slb_info in slbs_info:
            # 遍历slb的所有虚拟服务器组
            for vserver_group in slb_info["vserver_groups"]:
                # 修改虚拟服务器组
                for backend_server in vserver_group["BackendServer"]:
                    if backend_server["ServerId"] in gateway_server:
                        data = {
                            "account": slb_info["account"],
                            "slb_id": slb_info["id"],
                            "slb_name": slb_info["name"],
                            "vserver_group_name": vserver_group["VServerGroupName"],
                            "listenners": [
                                listener["Port"]
                                for listener in vserver_group['Listeners']
                            ]
                        }
                        data_info.append(data)
                        break

        df = pd.DataFrame(data_info)
        df.to_excel(f"slb_vserver信息.xlsx", index=False)
        self.logger.info("write vserver info toexcel success")


@logs()
def main():

    aliyun_slb_vserver = AliyunSlbVServer()
    # aliyun_slb_vserver.batch_modify_gateway_host()
    aliyun_slb_vserver.write_vserver_to_excel()

if __name__ == "__main__":
    main()